﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace XiaoYuStock.Model
{
    /// <summary>
    /// 作者：Ark
    /// 时间：2015.09.29
    /// 更新：改为非泛型类，加语言参数
    /// </summary>
    public static class BaseEnum
    {
        /// <summary>
        /// 作者：Ark
        /// 时间：2015.09.29
        /// 描述：枚举转整数
        /// </summary>
        /// <param name="value">枚举值</param>
        /// <returns></returns>
        public static long Value(this System.Enum value)
        {
            return Convert.ToInt64(value);
        }



      

        /// <summary>
        /// 作者：Jet
        /// 时间：2015-09-02
        /// 描述：通过SCode获取枚举列表
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static IEnumerable<long> GetEnumListByCode<T>(string code)
        {
            return GetEnumAttrList<T>().Where(m => m.Value.Scode == code).Select(m => m.Key).ToList();
        }

        /// <summary>
        /// 作者：Ark
        /// 时间：2015.09.29
        /// 描述：获取指定枚举的字典集合
        /// </summary>
        /// <param name="value"></param>
        /// <param name="platformType">平台类型</param>
        /// <returns></returns>
        private static Dictionary<long, BaseEnumAttribute> GetEnumAttrList(this System.Enum value)
        {
            var type = value.GetType();
            var dic = type.GetEnumAttrList();
            return dic;
        }


        /// <summary>
        /// 作者：Ark
        /// 时间：2015.09.29
        /// 描述：获取指定（枚举）值的简写码
        /// </summary>
        /// <param name="value">枚举值</param>
        /// <returns></returns>
        public static string GetScode(this System.Enum value)
        {
            var entity = value.GetEnumAttrList()[value.Value()];
            return entity!=null?entity.Scode.Trim(): string.Empty;
        }

        /// <summary>
        /// 作者：Ark
        /// 时间：2015.09.29
        /// 描述：获取指定（枚举）值的简写码
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetScodeByValue<T>(long? value)
        {
            if (!value.HasValue) return string.Empty;

            var dic = GetEnumAttrList<T>();

            if (!dic.ContainsKey(value.Value))
                return string.Empty;

            var entity = dic[value.Value];
            return entity==null?string.Empty:entity.Scode.Trim();
        }

        /// <summary>
        /// 作者：Ark
        /// 时间：2015.09.29
        /// 描述：获取指定（枚举）值的简写码
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetValue<T>(string propertyName, long? value)
        {
            if (!value.HasValue) return string.Empty;

            var dic = GetEnumAttrList<T>();

            if (!dic.ContainsKey(value.Value))
                return string.Empty;

            var entity = dic[value.Value];
            switch (propertyName.ToLower())
            {
                case "ename":
                    return entity==null?string.Empty:entity.Ename.Trim();
                case "cname":
                    return entity==null?string.Empty:entity.Cname.Trim();
                case "ordernum":
                    return entity==null?string.Empty:entity.OrderNum.ToString() ;
                case "scode":
                default:
                    return entity==null?string.Empty:entity.Scode.Trim();
                
            }
        }



        /// <summary>
        /// 作者：Ark
        /// 时间：2015.09.29
        /// 描述：获取指定枚举类型（T）的字典集合
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <returns></returns>
        public static Dictionary<long, BaseEnumAttribute> GetEnumAttrList<T>()
        {
            var type = typeof(T);
            var dic = type.GetEnumAttrList();
            return dic;
        }



        /// <summary>
        /// 作者：Elvis
        /// 时间：2015.10.15
        /// 描述：获取指定（枚举）值、语言的名称集合
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static IEnumerable<long> GetKeyByBinary(this System.Enum value)
        {
            var dic = value.GetEnumAttrList();
            var name = dic.Where(e => (e.Key & value.Value()) > 0).Select(e => e.Key).ToList();
            return name;
        }


       


        /// <summary>
        /// 作者：Ark
        /// 时间：2015.12.08
        /// 描述：返回 List 枚举
        /// </summary>
        /// <typeparam name="T">枚举</typeparam>
        /// <returns></returns>
        public static List<T> GetEnumList<T>()
        {
            var dic = new Dictionary<T, BaseEnumAttribute>();
            var type = typeof(T);
            var fields = type.GetFields();

            foreach (var field in fields.Where(field => field.FieldType.IsEnum))
            {
                foreach (var item in from attr in field.GetCustomAttributes(false) where null != attr select attr as BaseEnumAttribute)
                {
                    dic.Add((T)(field.GetValue(type)), item);
                }
            }

            return dic.OrderBy(o => o.Value.OrderNum).Select(o => o.Key).ToList();
        }
        /// <summary>
        /// 作者：Ark
        /// 时间：2015.09.29
        /// 描述：获取指定枚举类型（T）的字典集合
        /// </summary>
        /// <param name="type">枚举类型</param>
        /// <param name="platformType">平台类型</param>
        /// <returns></returns>
        private static Dictionary<long, BaseEnumAttribute> GetEnumAttrList(this Type type)
        {
            var dic = new Dictionary<long, BaseEnumAttribute>();
            var fields = type.GetFields();

            foreach (var field in fields.Where(field => field.FieldType.IsEnum))
            {
                foreach (var item in from attr in field.GetCustomAttributes(false) where null != attr select attr as BaseEnumAttribute)
                {
                    dic.Add(Convert.ToInt64(field.GetValue(type)), item);
                }
            }

            dic = dic.OrderBy(o => o.Value.OrderNum).ToDictionary(o => o.Key, o => o.Value);

            return dic;
        }

        /// <summary>
        /// 作者：Ark
        /// 时间：2016.04.12
        /// 描述：通过枚举值获取枚举
        /// </summary>
        /// <param name="value">枚举值</param>
        /// <param name="defaultT">获取不到返回默认值</param>
        /// <returns></returns>
        public static T GetEnum<T>(this long? value, T defaultT)
        {
            if (value.IsExist<T>())
            {
                return (T)System.Enum.ToObject(typeof(T), value.Value);
            }
            
            return defaultT;
        }


        /// <summary>
        /// 作者：Ark
        /// 时间：2015.10.21
        /// 描述：通过枚举值在枚举中是否存在
        /// </summary>
        /// <param name="value">枚举值</param>
        /// <returns></returns>
        private static bool IsExist<T>(this long? value)
        {
            if (!value.HasValue) return false;

            var dics = GetEnumAttrList<T>();
            return dics.ContainsKey(value.Value);
        }




        #region Enum Extensions

        /// <summary>
        /// 作者：Jet
        /// 日期：2014-12-31
        /// 描述：检测是否包含某值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool Has<T>(this System.Enum type, T value)
        {
            try
            {
                return (((long)(object)type & (long)(object)value) > 0);
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 作者：Jet
        /// 日期：2014-12-31
        /// 描述：添加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T Add<T>(this System.Enum type, T value)
        {
            try
            {
                return (T)(object)(((long)(object)type | (long)(object)value));
            }
            catch (Exception ex)
            {
               // throw new ArgumentException($"不能执行位运算{typeof(T).Name}.", ex);
            }
            return default(T);
        }

        /// <summary>
        /// 作者：Jet
        /// 日期：2014-12-31
        /// 描述：移出
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T Remove<T>(this System.Enum type, T value)
        {
            try
            {
                return (T)(object)(((long)(object)type & ~(long)(object)value));
            }
            catch (Exception ex)
            {
                throw new ArgumentException( string.Format("'不能执行位运算{0}'.", ex));
            }
        }

        /// <summary>
        /// 作者：Elvis
        /// 日期：2016-07-14
        /// 描述：多个值合并成一个(与运算)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumerable"></param>
        /// <returns></returns>
        public static T Join<T>(IEnumerable<T> enumerable) where T : struct
        {
            var temp = enumerable.Select(o => (long) (object) o);
            return (T)(object)temp.Aggregate((i, j) => i | j);
        }

        /// <summary>
        /// 作者：Elvis
        /// 日期：2016-07-14
        /// 描述：把一个值拆分成集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static List<T> Split<T>(T value) where T : struct
        {
            var list = new List<T>();
            var temp = (long)(object)value;
            for (long i = 1; i <= temp; i = i << 1)
            {
                if ((temp & i) > 0)
                {
                    list.Add((T)(object)i);
                }
            }
            return list;
        }



        #endregion
    }
}
